<template>
  <div class="app-container">
    <el-row :gutter="20">
      <!-- 用户列表 -->
      <el-col :span="6">
        <el-card class="user-list-card">
          <div slot="header" class="clearfix">
            <span>客户列表</span>
            <el-input
              placeholder="搜索客户"
              v-model="searchKeyword"
              clearable
              prefix-icon="el-icon-search"
              @input="searchUsers"
              size="small"
              style="margin-top: 10px;"
            ></el-input>
          </div>
          <div class="user-list">
            <div 
              v-for="user in filteredUsers" 
              :key="user.userId" 
              class="user-item" 
              :class="{ 'active': currentUser && currentUser.userId === user.userId }"
              @click="selectUser(user)"
            >
              <el-badge :value="user.unreadCount > 0 ? user.unreadCount : ''" class="user-badge">
                <div class="user-avatar">
                  <i class="el-icon-user-solid"></i>
                </div>
              </el-badge>
              <div class="user-info">
                <div class="user-name">{{ user.nickname }}</div>
                <div class="user-last-message">{{ user.lastMessage || '暂无消息' }}</div>
              </div>
              <div class="user-time" v-if="user.lastTime">{{ formatTime(user.lastTime) }}</div>
            </div>
            <el-empty description="暂无客户" v-if="filteredUsers.length === 0"></el-empty>
          </div>
        </el-card>
      </el-col>
      
      <!-- 聊天区域 -->
      <el-col :span="18">
        <el-card class="chat-card" v-loading="chatLoading">
          <div slot="header" class="clearfix" v-if="currentUser">
            <span>{{ currentUser.nickname }}</span>
            <span class="chat-user-info">{{ currentUser.phone }}</span>
          </div>
          <div v-if="!currentUser" class="chat-placeholder">
            <i class="el-icon-chat-dot-round"></i>
            <p>请选择一个客户开始聊天</p>
          </div>
          <template v-else>
            <!-- 聊天消息列表 -->
            <div class="chat-messages" ref="chatMessages">
              <div v-for="(message, index) in messages" :key="index" class="message-item" :class="{'self': message.fromUserId === serviceId}">
                <div class="message-avatar">
                  <i :class="message.fromUserId === serviceId ? 'el-icon-s-custom' : 'el-icon-user'"></i>
                </div>
                <div class="message-content">
                  <div class="message-bubble" :class="{'self': message.fromUserId === serviceId}">
                    <template v-if="message.messageType === '0'">
                      {{ message.content }}
                    </template>
                    <template v-else-if="message.messageType === '1'">
                      <img :src="message.content" class="message-image" @click="previewImage(message.content)" />
                    </template>
                  </div>
                  <div class="message-time">{{ formatTime(message.createTime) }}</div>
                </div>
              </div>
              <div ref="messageEnd" style="height: 1px;"></div>
            </div>
            
            <!-- 快捷回复 -->
            <div class="quick-reply">
              <el-dropdown @command="handleQuickReply" trigger="click">
                <el-button type="text" size="small">
                  快捷回复<i class="el-icon-arrow-down el-icon--right"></i>
                </el-button>
                <el-dropdown-menu slot="dropdown">
                  <el-dropdown-item v-for="(reply, index) in quickReplies" :key="index" :command="reply.content">
                    {{ reply.content }}
                  </el-dropdown-item>
                </el-dropdown-menu>
              </el-dropdown>
            </div>
            
            <!-- 输入框 -->
            <div class="chat-input">
              <el-input
                type="textarea"
                :rows="3"
                placeholder="请输入消息内容..."
                v-model="inputMessage"
                @keyup.enter.native.ctrl="sendMessage"
              ></el-input>
              <div class="chat-actions">
                <el-tooltip content="发送图片" placement="top">
                  <el-button type="text" icon="el-icon-picture" @click="openImageUpload"></el-button>
                </el-tooltip>
                <input 
                  type="file" 
                  ref="imageInput" 
                  accept="image/*" 
                  style="display: none" 
                  @change="handleImageUpload"
                />
                <span class="send-tip">Ctrl + Enter 发送</span>
                <el-button type="primary" size="small" @click="sendMessage" :disabled="!inputMessage.trim()">发送</el-button>
              </div>
            </div>
          </template>
        </el-card>
      </el-col>
    </el-row>

    <!-- 图片预览 -->
    <el-dialog :visible.sync="imagePreviewVisible" append-to-body width="50%">
      <img :src="previewImageUrl" style="width: 100%;" alt="图片预览">
    </el-dialog>
  </div>
</template>

<script>
import { 
  getChatUserList, 
  getChatHistory, 
  sendChatMessage, 
  markAsRead, 
  getQuickReplies,
  uploadChatImage
} from "@/api/company/chat";
import { getUserProfile } from "@/api/system/user";

export default {
  name: "CustomerService",
  data() {
    return {
      // 客服ID
      serviceId: "",
      // 客户列表
      userList: [],
      // 搜索关键词
      searchKeyword: "",
      // 当前选中的用户
      currentUser: null,
      // 聊天消息列表
      messages: [],
      // 输入框消息
      inputMessage: "",
      // 聊天加载状态
      chatLoading: false,
      // 快捷回复列表
      quickReplies: [],
      // 图片预览
      imagePreviewVisible: false,
      previewImageUrl: "",
      // WebSocket连接
      websocket: null,
      // 是否已连接WebSocket
      isConnected: false,
      // 心跳定时器
      heartbeatTimer: null
    };
  },
  computed: {
    filteredUsers() {
      if (!this.searchKeyword) {
        return this.userList;
      }
      return this.userList.filter(user => 
        user.nickname.toLowerCase().includes(this.searchKeyword.toLowerCase()) ||
        (user.phone && user.phone.includes(this.searchKeyword))
      );
    }
  },
  created() {
    this.initData();
  },
  mounted() {
    this.initWebSocket();
  },
  beforeDestroy() {
    this.closeWebSocket();
  },
  methods: {
    // 初始化数据
    async initData() {
      // 获取当前用户信息
      const userInfo = await getUserProfile();
      this.serviceId = userInfo.data.user.userId;
      
      // 获取客户列表
      this.getChatUsers();
      
      // 获取快捷回复
      this.getQuickReplyList();
    },
    // 获取客户列表
    getChatUsers() {
      this.chatLoading = true;
      getChatUserList().then(response => {
        this.userList = response.data;
        this.chatLoading = false;
      });
    },
    // 获取快捷回复列表
    getQuickReplyList() {
      getQuickReplies().then(response => {
        this.quickReplies = response.data;
      });
    },
    // 选择用户
    selectUser(user) {
      this.currentUser = user;
      this.getChatMessages();
    },
    // 获取聊天记录
    getChatMessages() {
      if (!this.currentUser) return;
      
      this.chatLoading = true;
      getChatHistory(this.currentUser.userId).then(response => {
        this.messages = response.data;
        this.chatLoading = false;
        // 标记消息为已读
        if (this.currentUser.unreadCount > 0) {
          markAsRead(this.currentUser.userId).then(() => {
            // 更新未读数
            this.currentUser.unreadCount = 0;
            // 更新用户列表中的未读数
            const userIndex = this.userList.findIndex(u => u.userId === this.currentUser.userId);
            if (userIndex !== -1) {
              this.userList[userIndex].unreadCount = 0;
            }
          });
        }
        this.$nextTick(() => {
          this.scrollToBottom();
        });
      });
    },
    // 发送消息
    sendMessage() {
      if (!this.currentUser || !this.inputMessage.trim()) return;
      
      const message = {
        toUserId: this.currentUser.userId,
        content: this.inputMessage.trim(),
        messageType: "0" // 文本消息
      };
      
      this.doSendMessage(message);
      this.inputMessage = "";
    },
    // 发送消息处理
    doSendMessage(message) {
      // 先添加到本地消息列表
      const localMessage = {
        id: new Date().getTime(),
        fromUserId: this.serviceId,
        toUserId: message.toUserId,
        content: message.content,
        messageType: message.messageType,
        readStatus: "0",
        createTime: new Date()
      };
      this.messages.push(localMessage);
      
      this.$nextTick(() => {
        this.scrollToBottom();
      });
      
      // 通过WebSocket发送
      if (this.isConnected) {
        this.sendWebSocketMessage(message);
      } else {
        // 如果WebSocket未连接，则通过HTTP发送
        sendChatMessage(message).then(response => {
          // 发送成功，更新用户列表中的最后消息
          this.updateUserLastMessage(message.toUserId, message.content);
        });
      }
    },
    // 处理快捷回复
    handleQuickReply(content) {
      this.inputMessage = content;
      this.sendMessage();
    },
    // 打开图片上传
    openImageUpload() {
      this.$refs.imageInput.click();
    },
    // 处理图片上传
    handleImageUpload(e) {
      const file = e.target.files[0];
      if (!file) return;
      
      // 验证文件类型
      const isImage = file.type.startsWith('image/');
      if (!isImage) {
        this.$message.error('请选择图片文件');
        return;
      }
      
      // 验证文件大小
      const isLt2M = file.size / 1024 / 1024 < 2;
      if (!isLt2M) {
        this.$message.error('图片大小不能超过 2MB!');
        return;
      }
      
      const formData = new FormData();
      formData.append('file', file);
      
      uploadChatImage(formData).then(res => {
        // 发送图片消息
        const message = {
          toUserId: this.currentUser.userId,
          content: res.data.url, // 图片URL
          messageType: "1" // 图片消息
        };
        
        this.doSendMessage(message);
      }).catch(error => {
        this.$message.error('图片上传失败');
      });
      
      // 清空文件选择器
      this.$refs.imageInput.value = '';
    },
    // 预览图片
    previewImage(url) {
      this.previewImageUrl = url;
      this.imagePreviewVisible = true;
    },
    // 滚动到底部
    scrollToBottom() {
      if (this.$refs.messageEnd) {
        this.$refs.messageEnd.scrollIntoView({ behavior: 'smooth' });
      }
    },
    // 更新用户最后消息
    updateUserLastMessage(userId, content) {
      const userIndex = this.userList.findIndex(u => u.userId === userId);
      if (userIndex !== -1) {
        this.userList[userIndex].lastMessage = content;
        this.userList[userIndex].lastTime = new Date();
        
        // 将该用户移到列表顶部
        const user = this.userList.splice(userIndex, 1)[0];
        this.userList.unshift(user);
      }
    },
    // 搜索用户
    searchUsers() {
      // 计算属性会自动处理
    },
    // 格式化时间
    formatTime(time) {
      if (!time) return '';
      
      const date = new Date(time);
      const now = new Date();
      const diff = now - date;
      
      // 今天内的消息只显示时间
      if (diff < 24 * 60 * 60 * 1000 && date.getDate() === now.getDate()) {
        return this.formatDateTime(date, 'HH:mm');
      }
      
      // 昨天的消息显示"昨天"
      const yesterday = new Date();
      yesterday.setDate(now.getDate() - 1);
      if (date.getDate() === yesterday.getDate() && date.getMonth() === yesterday.getMonth() && date.getFullYear() === yesterday.getFullYear()) {
        return '昨天 ' + this.formatDateTime(date, 'HH:mm');
      }
      
      // 一周内的消息显示星期几
      if (diff < 7 * 24 * 60 * 60 * 1000) {
        const weekdays = ['日', '一', '二', '三', '四', '五', '六'];
        return '星期' + weekdays[date.getDay()] + ' ' + this.formatDateTime(date, 'HH:mm');
      }
      
      // 其他情况显示完整日期
      return this.formatDateTime(date, 'yyyy-MM-dd HH:mm');
    },
    // 格式化日期时间
    formatDateTime(date, format) {
      const o = {
        'M+': date.getMonth() + 1,
        'd+': date.getDate(),
        'H+': date.getHours(),
        'm+': date.getMinutes(),
        's+': date.getSeconds()
      };
      
      if (/(y+)/.test(format)) {
        format = format.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
      }
      
      for (let k in o) {
        if (new RegExp('(' + k + ')').test(format)) {
          format = format.replace(RegExp.$1, RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length));
        }
      }
      
      return format;
    },
    // 初始化WebSocket
    initWebSocket() {
      const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
      const host = window.location.host;
      const wsUrl = `${protocol}//${host}/websocket/chat/${this.serviceId}`;
      
      this.websocket = new WebSocket(wsUrl);
      
      this.websocket.onopen = this.onWebSocketOpen;
      this.websocket.onmessage = this.onWebSocketMessage;
      this.websocket.onclose = this.onWebSocketClose;
      this.websocket.onerror = this.onWebSocketError;
    },
    // WebSocket连接成功
    onWebSocketOpen() {
      console.log('WebSocket连接成功');
      this.isConnected = true;
      
      // 开启心跳检测
      this.startHeartbeat();
    },
    // 接收WebSocket消息
    onWebSocketMessage(event) {
      try {
        const data = JSON.parse(event.data);
        
        // 处理心跳响应
        if (data.type === 'heartbeat') {
          console.log('收到心跳响应');
          return;
        }
        
        // 处理聊天消息
        if (data.type === 'chat') {
          const message = data.data;
          
          // 如果是当前聊天用户发来的消息
          if (this.currentUser && message.fromUserId === this.currentUser.userId) {
            this.messages.push(message);
            this.$nextTick(() => {
              this.scrollToBottom();
            });
            
            // 标记为已读
            markAsRead(message.fromUserId);
          } else {
            // 更新用户未读消息数
            const userIndex = this.userList.findIndex(u => u.userId === message.fromUserId);
            if (userIndex !== -1) {
              this.userList[userIndex].unreadCount = (this.userList[userIndex].unreadCount || 0) + 1;
              this.userList[userIndex].lastMessage = message.content;
              this.userList[userIndex].lastTime = message.createTime;
              
              // 将该用户移到列表顶部
              const user = this.userList.splice(userIndex, 1)[0];
              this.userList.unshift(user);
            } else {
              // 如果用户不在列表中，刷新用户列表
              this.getChatUsers();
            }
          }
        }
      } catch (error) {
        console.error('处理WebSocket消息出错', error);
      }
    },
    // WebSocket连接关闭
    onWebSocketClose() {
      console.log('WebSocket连接关闭');
      this.isConnected = false;
      this.stopHeartbeat();
      
      // 尝试重连
      setTimeout(() => {
        this.initWebSocket();
      }, 5000);
    },
    // WebSocket连接错误
    onWebSocketError(error) {
      console.error('WebSocket连接错误', error);
      this.isConnected = false;
    },
    // 关闭WebSocket连接
    closeWebSocket() {
      if (this.websocket) {
        this.stopHeartbeat();
        this.websocket.close();
      }
    },
    // 通过WebSocket发送消息
    sendWebSocketMessage(message) {
      if (!this.isConnected) return false;
      
      try {
        this.websocket.send(JSON.stringify({
          type: 'chat',
          data: message
        }));
        return true;
      } catch (error) {
        console.error('发送WebSocket消息失败', error);
        return false;
      }
    },
    // 开始心跳检测
    startHeartbeat() {
      this.heartbeatTimer = setInterval(() => {
        if (this.isConnected) {
          try {
            this.websocket.send(JSON.stringify({
              type: 'heartbeat',
              data: 'ping'
            }));
          } catch (error) {
            console.error('发送心跳消息失败', error);
            this.closeWebSocket();
          }
        }
      }, 30000); // 30秒发送一次心跳
    },
    // 停止心跳检测
    stopHeartbeat() {
      if (this.heartbeatTimer) {
        clearInterval(this.heartbeatTimer);
        this.heartbeatTimer = null;
      }
    }
  }
};
</script>

<style scoped>
.user-list-card, .chat-card {
  height: calc(100vh - 130px);
  display: flex;
  flex-direction: column;
}

.user-list {
  flex: 1;
  overflow-y: auto;
  margin-right: -10px;
  padding-right: 10px;
}

.user-item {
  display: flex;
  align-items: flex-start;
  padding: 12px;
  border-radius: 4px;
  cursor: pointer;
  transition: background-color 0.2s;
  position: relative;
  margin-bottom: 5px;
}

.user-item:hover {
  background-color: #f5f7fa;
}

.user-item.active {
  background-color: #ecf5ff;
}

.user-badge {
  margin-right: 10px;
}

.user-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background-color: #f0f2f5;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
  color: #909399;
}

.user-info {
  flex: 1;
  min-width: 0;
}

.user-name {
  font-size: 14px;
  font-weight: 500;
  margin-bottom: 5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.user-last-message {
  font-size: 12px;
  color: #909399;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.user-time {
  font-size: 12px;
  color: #909399;
  position: absolute;
  top: 12px;
  right: 12px;
}

.chat-card {
  padding: 0;
}

.chat-card >>> .el-card__header {
  padding: 15px 20px;
  border-bottom: 1px solid #ebeef5;
}

.chat-card >>> .el-card__body {
  padding: 0;
  display: flex;
  flex-direction: column;
  flex: 1;
  overflow: hidden;
}

.chat-user-info {
  margin-left: 10px;
  font-size: 14px;
  color: #909399;
  font-weight: normal;
}

.chat-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: #909399;
}

.chat-placeholder i {
  font-size: 60px;
  margin-bottom: 20px;
}

.chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 20px;
}

.message-item {
  display: flex;
  margin-bottom: 20px;
}

.message-item.self {
  flex-direction: row-reverse;
}

.message-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background-color: #f0f2f5;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
  color: #909399;
  margin: 0 10px;
}

.message-content {
  max-width: 70%;
}

.message-bubble {
  padding: 10px 15px;
  border-radius: 8px;
  background-color: #f2f6fc;
  position: relative;
  word-break: break-word;
}

.message-bubble.self {
  background-color: #e1f3ff;
  color: #333;
}

.message-time {
  font-size: 12px;
  color: #909399;
  margin-top: 5px;
  text-align: right;
}

.message-item.self .message-time {
  text-align: left;
}

.message-image {
  max-width: 200px;
  max-height: 200px;
  cursor: pointer;
}

.quick-reply {
  padding: 10px 20px;
  border-top: 1px solid #ebeef5;
  background-color: #f8f8f8;
}

.chat-input {
  padding: 15px 20px;
  border-top: 1px solid #ebeef5;
}

.chat-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 10px;
}

.send-tip {
  font-size: 12px;
  color: #909399;
}
</style> 